#include "xsUI.hpp"

namespace xs
{

UISystem g_ui;

//=================================================================================================
// UISystem::UISystem
//=========

UISystem::UISystem(): m_root(0), m_event_rec(0), m_left_pressed(false), m_active(0)
{
}

//=================================================================================================
// UISystem::gen_event
//=========

void UISystem::gen_event(int event, Window *sender)
{
	if(m_event_rec)
	{
		m_event_rec->on_event(event, sender);
	}
}

//=================================================================================================
// UISystem::root_dfs
//=========

void UISystem::root_dfs(UIVisitor *visitor)
{
	if(m_root) m_root->accept(visitor);
}

//=================================================================================================
// UISystem::mouse
//=========

void UISystem::mouse(float x, float y, xs::MouseEventType event)
{
	static float last_x=0, last_y=0;

	if(event == xs::MouseEvents::LMB_DOWN)
	{
		m_left_pressed = true;
		if(m_root) 
		{
			Window *mouse_over = m_root->get_window_at(x, y);
			m_active = mouse_over;
			if(mouse_over)
			{
				float real_x=0, real_y=0;
				mouse_over->get_real_pos(real_x, real_y);
				mouse_over->on_lmb_down(x-real_x, y-real_y);
			}
		}
	}
	if(event == xs::MouseEvents::LMB_UP)
	{
		m_left_pressed = false;
		if(m_root)
		{
			Window *mouse_over = m_root->get_window_at(x, y);
			if(mouse_over && mouse_over==m_active)
			{						
				float real_x=0, real_y=0;
				mouse_over->get_real_pos(real_x, real_y);
				mouse_over->on_lmb_up(x-real_x, y-real_y);
			}
		}
	}

	if(event == xs::MouseEvents::MOVE)
	{
		if(m_root)
		{
			Window *mouse_over = m_root->get_window_at(last_x, last_y);
			if(mouse_over && mouse_over==m_active)
			{
				float real_x=0, real_y=0;
				mouse_over->get_real_pos(real_x, real_y);
				mouse_over->on_mouse_move(x-real_x, y-real_y, x-last_x, y-last_y, m_left_pressed);
			}
		}

		last_x = x; last_y = y;
	}

	if(m_root)
	{
		m_root->clear_state();

		Window *mouse_over = m_root->get_window_at(x, y);
		if(mouse_over)
		{
			if(m_left_pressed && mouse_over == m_active)
				mouse_over->state = UIS_PRESSED;

			if(!m_left_pressed)
				mouse_over->state = UIS_FOCUSED;
		}
	}
}

//=================================================================================================
// UISystem::key
//=========

void UISystem::key(u32 code, bool down)
{
	if(m_active)
	{
		if(down)
			m_active->on_key_down(code);
		else
			m_active->on_key_up(code);
	}
}

//=================================================================================================
// UISystem::set_event_rec
//=========

void UISystem::set_event_rec(UIEventRec *new_rec)
{
	m_event_rec = new_rec;
}

//=================================================================================================
// UISystem::set_root
//=========

void UISystem::set_root(Window *wnd)
{
	m_root = wnd;
	m_active = m_root;
}

//=================================================================================================
// UISystem::type
//=========

void UISystem::type(wchar_t c)
{
	if(m_active)
	{
		m_active->on_type(c);
	}
}

//=================================================================================================
// UISystem::get_active
//=========

Window* UISystem::get_active()
{
	return m_active;
}

}